﻿using K8.MDCBB;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using static System.Runtime.InteropServices.JavaScript.JSType;

namespace KingerRobot.PCRBW.Biz;
/**
 * 桁架2业务处理（作废）
 * */
public class Truss2TaskBiz : K8.MDCBB.Biz
{
    #region 配置参数
    private ParamData Param { get; set; }

    class ParamData
    {
        /// <summary>
        ///桁架Id
        /// </summary>
        public long EquipId { get; set; }
        /// <summary>
        ///滑台1
        /// </summary>
        public long Sd1Id { get; set; }
        /// <summary>
        ///滑台1
        /// </summary>
        public long Sd2Id { get; set; }
    }
    #endregion

    #region PLC 通讯参数
    private ValueData Data { get; set; }
    class ValueData
    {
        #region 桁架点位
        /// <summary>
        /// 交互标志位
        /// </summary>
        public int GantryMark { get; set; }
        /// <summary>
        /// 桁架自动流程
        /// </summary>
        public int ClearWCSFlag { get; set; }
        /// <summary>
        ///K=1 桁架运行任务；K=2 桁架空闲 ；K=3 桁架故障；K=4 桁架手动
        /// </summary>
        public int GantryStatus { get; set; }
        /// <summary>
        /// 桁架自动流程
        /// </summary>
        public int GantryAutoStep { get; set; }
      
        /// <summary>
        /// 反馈上位机报警字00
        /// </summary>
        public int AlarmToWCS00 { get; set; }
        /// <summary>
        /// 反馈上位机报警字00
        /// </summary>
        public int AlarmToWCS01 { get; set; }
        /// <summary>
        /// 反馈上位机报警字00
        /// </summary>
        public int AlarmToWCS02 { get; set; }
        /// <summary>
        /// 反馈上位机报警字00
        /// </summary>
        public int AlarmToWCS03 { get; set; }
        /// <summary>
        /// 反馈上位机报警字00
        /// </summary>
        public int AlarmToWCS04 { get; set; }
        /// <summary>
        /// 反馈上位机报警字00
        /// </summary>
        public int AlarmToWCS05 { get; set; }
        /// <summary>
        /// 指令流水号
        /// </summary>
        public int SerialNumber { get; set; }

        /// <summary>
        /// 反馈指令流水号
        /// </summary>
        public int ReSerialNumber { get; set; }

        #endregion

        #region 滑台
        /// <summary>
        /// 1#出库滑台有货（允许桁架取）
        /// </summary>
        public int OutHasGood1 { get; set; }
        /// <summary>
        ///2#出库滑台有货（允许桁架取）
        /// </summary>
        public int OutHasGood2 { get; set; }

        /// <summary>
        /// 取Z上位坐标
        /// </summary>
        public int GetUpZPosition { get; set; }

        /// <summary>
        /// 放Z上位坐标
        /// </summary>
        public int SetUpZPosition { get; set; }
        /// <summary>
        /// 取Z下位坐标
        /// </summary>
        public int GetLowerZPosition { get; set; }
        /// <summary>
        /// 放Z下位坐标
        /// </summary>
        public int SetLowerZPosition { get; set; }
        #endregion
    }
    #endregion

    #region 缓存
    private CacheData Cache { get; set; }
    class CacheData
    {
        public int FinalTaskNo { get; set; }
    }
    #endregion

    #region 实时日志
    private StepData Step { get; set; }
    class StepData
    {
        private string _msg = string.Empty;
        public string StepMsg
        {
            get
            {
                return this._msg;
            }
            set
            {
                if (string.IsNullOrWhiteSpace(value))
                {
                    this._msg = string.Empty;
                    return;
                }
                this._msg = $"{System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")}>>{value}";
            }
        }
    }
    private void StepMsg(string msg)
    {
        this.Step.StepMsg = msg;
        this.WriteLog(msg);
    }
    #endregion

    #region 文件日志（运行需要 Nlog 配置）
    private void WriteLog(string message)
    {
        K8.LSF.Client.Log(new K8.LSF.Log { Data = message });
    }
    #endregion

    /// <summary>
    /// 和 PLC 通讯对象
    /// </summary>
    private BizData BizData { get; set; }
    public int Execute(BizData writer)
    {
        // Excute 方法外使用 BizParam
        this.BizData = writer;
        // 返回参数
        var result = 0;
        int errorNo = 0; // 设备故障
        string errorMsg = string.Empty;


        #region 设备手动或者故障  

        if (Data.GantryStatus == (int)EnumGantryStatus.Fault)
        {
            errorNo = Data.GantryStatus;
            errorMsg = QueryAlarmMessage();//将解析的错误编码返回
            this.StepMsg($"桁架任务》桁架{Param.EquipId} |故障Value.errorNo{Data.GantryStatus}");
        }
        Alarm.Instance.AddAlarm(Param.EquipId, errorNo, errorMsg);//更新报警 TODO  将报警信息记录到数据库中

        if (Data.GantryStatus == (int)EnumGantryStatus.Manual || Data.GantryStatus == (int)EnumGantryStatus.Fault)
        {
            this.StepMsg($"桁架任务》桁架[{Param.EquipId}]-[{Data.GantryStatus}]故障或者未进入自动");
            return result;
        }
        #endregion

        #region 桁架运行状态验证
        this.StepMsg($"桁架任务》桁架{Param.EquipId}任务》运行状态:{Data.GantryStatus}");
        if (Data.GantryStatus != (int)EnumGantryStatus.Free || Data.GantryMark != 2)
        {
            this.StepMsg($"桁架任务》桁架{Param.EquipId}任务》不可写或非空闲状态 GantryStatus-{Data.GantryStatus}，GantryMark-{Data.GantryMark}");
            return result;
        }
        #endregion

        #region 结束任务
        if (Data.SerialNumber > 0 && Data.ReSerialNumber > 0 && Data.SerialNumber != Data.ReSerialNumber)
        {
            this.StepMsg($"桁架任务》桁架{Param.EquipId}任务》写流水号与反馈流水号不一致 SerialNumber-{Data.SerialNumber}，ReSerialNumber-{Data.ReSerialNumber}");
            return 0;
        }
        //龙门下发任务完成写入1，PLC接收写入2|0
        if (Data.GantryMark == 1)
        {  //1表示PLC还未读取 禁止下步操作
            this.StepMsg($"桁架任务》桁架{Param.EquipId}任务》PLC还未读取");
            return result;
        }
        //龙门反馈任务完成，关闭任务
        if (Data.SerialNumber > 0 && Data.SerialNumber == Data.ReSerialNumber && Data.SerialNumber != Cache.FinalTaskNo)
        {
            this.StepMsg($"桁架任务》桁架{Param.EquipId}任务》结束桁架任务[{Data.ReSerialNumber}]");

            FinishGantryTask();
        }
        #endregion

        #region 根据滑台完成信号，生成任务
        var trussService = K8.RSF.Client.Create<ITrussOrderService>();
        long equipId = Param.EquipId;
        //获取出库滑台到位信号 开始生成桁架任务targetName
        if (Data.OutHasGood2 == 1)
        {
            trussService.CreateTask(equipId, "M2104");
        }

        #endregion

        // 根据指令查询可执行的桁架任务
        this.StepMsg($"桁架任务》桁架{Param.EquipId}任务4");

        var taskAndCmd = trussService.GetTrussTaskAndCmdBeanByCmdEquipId(equipId);
        this.StepMsg($"桁架任务》桁架{Param.EquipId}任务44>{taskAndCmd.Count()}");
        if (taskAndCmd is null || taskAndCmd.Count == 0)
        {
            this.StepMsg($"桁架任务》桁架{Param.EquipId}任务》未查询到任务指令！");
            return result;
        }
        foreach (var item in taskAndCmd)
        {
            if (item.GetRcsLocation.Id == Param.Sd1Id && Data.OutHasGood1 != 1)
            {
                this.StepMsg($"桁架任务》桁架{Param.EquipId}任务》出库滑台1有货不可放货 ！状态：[{Data.OutHasGood1}]");
                continue;
            }
            if (item.GetRcsLocation.Id == Param.Sd2Id && Data.OutHasGood2 != 1)
            {
                this.StepMsg($"桁架任务》桁架{Param.EquipId}任务》出库滑台2有货不可放货 ！状态：[{Data.OutHasGood2}]");
                continue;
            }

            //出入库滑台取放圈位置计算
            double up = 0;
            double innerdiameter = (double.Parse(item.WcsTaskCmd.Innerdiameter.ToString()) * 25.4) / 2;
            double down = 0;
            //库位取圈位置计算
            double upStore = 0;
            double downStore = 0;

            #region 桁架任务
            //桁架任务 异常滑台放货

            //滑台
            if (item.GetRcsLocation.LocType == 4 && item.GetRcsLocation.LocCode == "M2103")
            {
                up = 1990;
                down = 2000;
            }
            if (item.GetRcsLocation.LocType == 4 && item.GetRcsLocation.LocCode == "M2104")
            {
                up = 1990;
                down = 2000;
            }
            //机台
            if (item.SetRcsLocation.LocType == 7)
            {
                upStore = 2300;
                downStore = 2350;
            }
            #endregion

            // 下发
            //var task = new
            //{
            //    SerialNumber = item.WcsTaskCmd.TaskNo,//任务流水号
            //    GetPlatformNumber = "6101",
            //    GetXPosition = 238,//取料X
            //    GetYPosition = 790,//取料Y
            //    SetPlatformNumber = "8101",
            //    SetXPosition = 8826,//放料X
            //    SetYPosition = 800,//放料Y
            //    GetUpZPosition = up,//取Z上位坐标
            //    GetLowerZPosition = down,//取Z下位坐标
            //    SetUpZPosition = upStore,//放Z上位坐标
            //    SetLowerZPosition = downStore,//放Z下位坐标
            //    Innerdiameter = item.WcsTaskCmd.Innerdiameter
            //};
            var task = new
            {
                SerialNumber = item.WcsTaskCmd.TaskNo,//任务流水号
                GetPlatformNumber = "6101",
                GetXPosition = item.GetRcsLocation.AxisX,//取料X
                GetYPosition = item.GetRcsLocation.AxisY,//取料Y
                SetPlatformNumber = "8101",
                SetXPosition =  item.SetRcsLocation.AxisX,//放料X
                SetYPosition = item.SetRcsLocation.AxisY,// 放料Y
                GetUpZPosition = up,//取Z上位坐标
                GetLowerZPosition = down,//取Z下位坐标
                SetUpZPosition = upStore,//放Z上位坐标
                SetLowerZPosition = downStore,//放Z下位坐标
                Innerdiameter = item.WcsTaskCmd.Innerdiameter
            };
            var mark = writer.WriteData(task);
            this.StepMsg($"桁架任务》桁架{equipId}任务》写入PLC [{mark}]！");
            if (mark > 0)
            {
                mark = this.BizData.WriteData(new
                {
                    GantryMark = 1,
                    CommandCode = 1
                });
                this.StepMsg($"桁架任务》桁架{equipId}》下发任务标识:{mark}");
                if (mark > 0)
                {
                    mark = trussService.ExecuteTask(item.WcsTaskCmd.TargetLoc.GetValueOrDefault(), item.WcsTaskCmd.TaskNo.GetValueOrDefault());
                    this.StepMsg($"桁架任务》桁架{equipId}>下发PLC成功:{mark}");
                }
            }
            break;
        }
        return result;
    }

    private int FinishGantryTask()
    {
        int finishResult = 0;
        this.StepMsg($"桁架任务》桁架{Param.EquipId}》开始完成任务");
        var taskService = K8.RSF.Client.Create<ITrussOrderService>();
        //结束上次任务
        finishResult = taskService.FinishTask(Data.SerialNumber);

        if (finishResult > 0)
        {
            Cache.FinalTaskNo = Data.ReSerialNumber;//流水号缓存          
        }
        this.StepMsg($"桁架任务》桁架{Param.EquipId}》完成任务结束");
        return finishResult;
    }

    public string QueryAlarmMessage()
    {
        string result = string.Empty;
        List<string> list = new List<string>();
        list.Add(Data.AlarmToWCS00.ToString());
        list.Add(Data.AlarmToWCS01.ToString());
        list.Add(Data.AlarmToWCS02.ToString());
        list.Add(Data.AlarmToWCS03.ToString());
        list.Add(Data.AlarmToWCS04.ToString());
        list.Add(Data.AlarmToWCS05.ToString());
        return list.ToJson();
    }
}
